<?php
/**
 * Copyright 2010 Dave Keen
 * http://www.actionscriptdeveloper.co.uk
 *
 * This file is part of Flextrine.
 *
 * Flextrine is free software: you can redistribute it and/or modify
 * it under the terms of the Lesser GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * Lesser GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * and the Lesser GNU General Public License along with this program.
 * If not, see <http://www.gnu.org/licenses/>.
 *
 */

 use Doctrine\Common\Cache\ApcCache,
     Doctrine\ORM\Configuration,
     Doctrine\ORM\EntityManager,
	 Doctrine\ORM\Mapping\Driver\AnnotationDriver,
	 Doctrine\Common\Annotations\AnnotationReader;
 

// We need to bootstrap Doctrine class loaders for Doctrine, vo and the proxies.  Since this is done in gateway.php before the
// service call itself there is no need to include or require in any Flextrine service.
require_once "Doctrine/Common/ClassLoader.php";

$doctrineClassLoader = new \Doctrine\Common\ClassLoader("Doctrine");
$doctrineClassLoader->register();
$doctrineClassLoader = new \Doctrine\Common\ClassLoader("Flextrine");
$doctrineClassLoader->register();
$entitiesClassLoader = new \Doctrine\Common\ClassLoader(null, dirname(__FILE__)."/entities");
$entitiesClassLoader->register();
$proxiesClassLoader = new \Doctrine\Common\ClassLoader("Proxies", dirname(__FILE__)."/Proxies");
$proxiesClassLoader->register();

/**
 * The Config object retrieves settings from config.php, sets them as static properties, creates and configures the EntityManager and configures AMF class mapping.
 */
class Config {
	static $connectionOptions;
	static $flextrineManagerEnabled;
	static $entityDir;
	static $proxyDir;
	static $serviceDir;
	
	static $em;
	
	static function populateConfig() {
		// Retrieve variables from config.php and set them in Config
		include("config.php");
		if (isset($flextrineIncludePath)) set_include_path(get_include_path().PATH_SEPARATOR.$flextrineIncludePath);
		self::$connectionOptions = $connectionOptions;
		self::$flextrineManagerEnabled = $flextrineManagerEnabled;
		self::$entityDir = $entityDir;
		self::$proxyDir = $proxyDir;
		self::$serviceDir = $serviceDir;
		
		// Create the EntityManager
		self::createEntityManager();
		
		// Configure the service and value object paths
		self::configureAMFPHPPaths();
		
		// Configure AMF class mappings
		self::configureClassMappings();
		
	}
	
	private static function createEntityManager() {
		// Configure and construct the EntityManager
		$config = new Configuration();
		$cache = new ApcCache();
		
		//$config->setMetadataCacheImpl($cache);
		//$config->setQueryCacheImpl($cache);

		$config->setProxyDir(self::$proxyDir);
		$config->setProxyNamespace("Proxies");
		$config->setAutoGenerateProxyClasses(true);

		$reader = new AnnotationReader();
		$reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
		$driverImpl = new AnnotationDriver($reader, array(self::$entityDir));
		$config->setMetadataDriverImpl($driverImpl);

		// Create EntityManager and put it into Config
		self::$em = EntityManager::create(Config::$connectionOptions, $config);
	}
	
	/**
	 * Configure the service and value object path for AMFPHP.  Unfortunately we need to use global :(
	 */
	private static function configureAMFPHPPaths() {
		global $voPath, $servicesPath;
		
		$voPath = self::$entityDir;
		$servicesPath = self::$serviceDir;
	}
	
	/**
	 * Configure AMF class mappings in both directions.  As well as mapping dot notation to PHP namespace notation this also maps Doctrine Proxy objects to their
	 * matchin AS3 entity classes (as there is no concept of a Proxy in client-side Flextrine).
	 */
	private static function configureClassMappings() {
		$GLOBALS['amfphp']['outgoingClassMappings'] = array();
		$GLOBALS['amfphp']['incomingClassMappings'] = array();
		foreach (self::$em->getMetadataFactory()->getAllMetadata() as $metadata) {
			$phpClassName = $metadata->name;
			$as3ClassName = str_replace("\\", ".", $metadata->name);
			
			$GLOBALS['amfphp']['incomingClassMappings'][$as3ClassName] = $phpClassName;
			$GLOBALS['amfphp']['outgoingClassMappings'][strtolower($phpClassName)] = $as3ClassName;
			$GLOBALS['amfphp']['outgoingClassMappings']["proxies\\".strtolower(str_replace("\\", "", $metadata->name)."proxy")] = $as3ClassName;
		}
	}
	
}
Config::populateConfig();

?>